package com.shop.cereshop.business.dl.logic.service;


import com.alibaba.fastjson.JSONObject;
import com.shop.cereshop.business.dao.after.CereOrderAfterDAO;
import com.shop.cereshop.business.dao.order.CereShopOrderDAO;
import com.shop.cereshop.business.dl.logic.domian.*;
import com.shop.cereshop.business.dl.logic.utils.JsonUtils;
import com.shop.cereshop.business.page.after.Refund;
import com.shop.cereshop.business.pay.weixin.service.WxPayService;
import com.shop.cereshop.business.redis.service.api.StringRedisService;
import com.shop.cereshop.business.service.log.CerePlatformLogService;
import com.shop.cereshop.business.service.pay.CerePayLogService;
import com.shop.cereshop.business.service.redis.CereRedisKeyServcice;
import com.shop.cereshop.commons.constant.CoReturnFormat;
import com.shop.cereshop.commons.constant.StringEnum;
import com.shop.cereshop.commons.constant.WxPayEnum;
import com.shop.cereshop.commons.domain.after.CereOrderAfter;
import com.shop.cereshop.commons.domain.order.CereShopOrder;
import com.shop.cereshop.commons.domain.pay.CerePayLog;
import com.shop.cereshop.commons.exception.CoBusinessException;
import com.shop.cereshop.commons.utils.EmptyUtils;
import com.shop.cereshop.commons.utils.TimeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;


/**
 * @description 远程接口调用
 * @Author YF
 * @Date 日期:2021/5/20 时间:14:12
 */
@Service
public class SendPostImpl {

    @Autowired
    private RestTemplate restTemplate;
    @Value("${Dl_Data.version}")
    private String version;
    @Value("${Dl_Data.userId}")
    private String user_id;
    @Value("${Dl_Data.name}")
    private String user_key;
    @Value("${Dl_Data.buyerUserId}")
    private Long buyerUserId;


    @Autowired
    private CereOrderAfterDAO cereOrderAfterDAO;
    @Autowired
    private StringRedisService stringRedisService;
    @Autowired
    private WxPayService wxPayService;

    @Autowired
    private CereRedisKeyServcice cereRedisKeyServcice;

    @Autowired
    private CerePayLogService cerePayLogService;

    @Autowired
    private CerePlatformLogService cerePlatformLogService;

    @Autowired
    private CereShopOrderDAO cereShopOrderDAO;

    /**
     * @param
     * @description:获取产品信息
     * @return:
     * @author:作者:YF
     * @time:日期:2021/5/19 时间:13:53
     */
    public String GetProductInfo(Integer pageIndex,Integer pageSize,String productNo,String sceneryNo,String productType) {
        JSONObject json = new JSONObject();
        //定义返回值(第一个未解密，第二个已解密)
//        final String[] data = new String[1];
//        final String[] decryptData = new String[1];
        String result = new String();
        //.定义方法
        String method = "GetProductInfo";
        //定义时间
        long st = System.currentTimeMillis() / 1000;
        //加密将json格式的业务参数进行des加密，加密模式ECB充方式 PKCS7Padding,密钥为user_key。
        String encrypt = null;
        try {
            json.put("pageIndex",pageIndex);
            json.put("pageSize",pageSize);
            json.put("productNo",productNo);
            json.put("sceneryNo",sceneryNo);
            json.put("productType",productType);
            encrypt = encrypt("{" + "pageIndex:"+json.get("pageIndex")+","+"pageSize:"+json.get("pageSize")+","+"productNo:"+json.get("productNo")+","
                    +"sceneryNo:"+json.get("sceneryNo")+","
                    +"productType:"+json.get("productType")+ "}", user_key);
        } catch (Exception e) {
            e.printStackTrace();
        }
        String md5 = getMD5(user_id + method + st + version + encrypt + user_key);
        //.封装JSON格式数据
        RequestHead requestHead = new RequestHead();
        requestHead.setUser_id(user_id);
        requestHead.setMethod(method);
        requestHead.setTimestamp(st);
        requestHead.setVersion(version);
        requestHead.setSign(md5);
        json.put("requestHead", requestHead);
        json.put("requestBody", encrypt);
        //.请求地址URL
        String url = "http://service.zhuxiaoke.cn/Tongcheng/ProcessRequest/";
        //远程调用
        String resultInfo = restTemplate.postForObject(url, json, String.class);
        
        try {
            //解密
            result = decrypt((String) JsonUtils.toMap(resultInfo).get("responseBody"), user_key);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (result!=null){
            System.err.println("远程调用助销客接口成功");
        }else {
            System.err.println("远程调用助销客接口失败");
        }
        return result;
        //.创建异步远程调用Client
//        CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault();
//        httpclient.start();
//        final CountDownLatch latch = new CountDownLatch(1);
//        final HttpPost post = new HttpPost(url);
//        try {
//            post.setEntity(new StringEntity(json.toString()));
//        } catch (UnsupportedEncodingException e) {
//            e.printStackTrace();
//        }
//        //.发送异步请求
//        httpclient.execute(post, new FutureCallback<HttpResponse>() {
//            @Override
//            public void completed(final HttpResponse response) {
//                latch.countDown();
//                System.out.println(" callback thread id is : " + Thread.currentThread().getId());
//                System.out.println(post.getRequestLine() + "->" + response.getStatusLine());
//                try {
//                    data[0] = EntityUtils.toString(response.getEntity(), "UTF-8");
//                    System.out.println(" response content is : " + data[0]);
//                    decryptData[0] = decrypt((String) JsonUtils.toMap(data[0]).get("responseBody"), "xmxm1231");
//                    System.out.println(decryptData[0]);
//                } catch (IOException e) {
//                    e.printStackTrace();
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//            }
//
//
//            @Override
//            public void failed(final Exception ex) {
//                latch.countDown();
//                System.out.println(post.getRequestLine() + "->" + ex);
//                System.out.println(" 发送异步请求失败: " + Thread.currentThread().getId());
//            }
//
//            @Override
//            public void cancelled() {
//                latch.countDown();
//                System.out.println(post.getRequestLine() + " cancelled");
//                System.out.println(" 取消异步请求 : " + Thread.currentThread().getId());
//            }
//        });
//
//        try {
//            latch.await();
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//
//        try {
//            httpclient.close();
//        } catch (IOException ignore) {
//
//        }
//        System.out.println("最终数据："+decryptData[0]);
//        return decryptData[0];


    }


    /**
     * @param
     * @description: 产品价格日历
     * @return:
     * @author:作者:YF
     * @time:日期:2021/5/20 时间:15:27
     */
    public String GetCalenderPrice(Integer productNo,String startTime,String endTime) {
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        String startTimeS = sdf.format(new Date(Long.parseLong(String.valueOf(startTime))));
        String endTimeS = sdf.format(new Date(Long.parseLong(String.valueOf(endTime))));

        JSONObject json = new JSONObject();
        //.返回参数
        String result = new String();
        //.定义时间
        long st = System.currentTimeMillis() / 1000;
        //.定义方法
        String method = "GetCalenderPrice";
        //加密将json格式的业务参数进行des加密，加密模式ECB充方式 PKCS7Padding,密钥为user_key。
        String encrypt = null;
        try {
            json.put("productNo",productNo);
            json.put("startTime",startTimeS);
            json.put("endTime",endTimeS);

            encrypt = encrypt("{" + "productNo:"+json.get("productNo")+","+"startTime:"+"\""+json.get("startTime")+"\""+","+
                    "endTime:"+"\""+json.get("endTime")+"\""+ "}", user_key);
            System.out.println(decrypt(encrypt,user_key));
        } catch (Exception e) {
            e.printStackTrace();
        }
        String md5 = getMD5(user_id + method + st + version + encrypt + user_key);
        //.封装JSON格式数据

        RequestHead requestHead = new RequestHead();
        requestHead.setUser_id(user_id);
        requestHead.setMethod(method);
        requestHead.setTimestamp(st);
        requestHead.setVersion(version);
        requestHead.setSign(md5);
        json.put("requestHead", requestHead);
        json.put("requestBody", encrypt);
        //.请求地址URL
        String url = "http://service.zhuxiaoke.cn/Tongcheng/ProcessRequest/";
        //.发送请求
        String resultInfo = restTemplate.postForObject(url, json, String.class);
        System.out.println(resultInfo);
        try {
            result = decrypt((String) JsonUtils.toMap(resultInfo).get("responseBody"), user_key);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(result);
        return result;
    }


    /**
     * @param
     * @description:订单接口(下订单)
     * @author:作者:YF
     * @time:日期:2021/5/20 时间:16:36
     */
    public String CreateOrder(String orderSerialId, String productNo, Integer payType, Integer tickets, Long price, Long contractPrice, String bookName, String bookMobile,
                              String idCard, String travelDate, String departDate, String bookBeginTime, String bookEndTime, List<VisitPerson> visitPerson, Address address) {
        JSONObject json = new JSONObject();
        StringBuffer buffer = new StringBuffer("");
        buffer.append("{");
        buffer.append("orderSerialId:\""+orderSerialId+"\",");
        buffer.append("productNo:\""+productNo+"\",");
        buffer.append("payType:"+payType+",");
        buffer.append("tickets:"+tickets+",");
        buffer.append("price:"+price+",");
        buffer.append("contractPrice:"+contractPrice+",");
        buffer.append("bookName:\""+bookName+"\",");
        buffer.append("bookMobile:\""+bookMobile+"\",");
        buffer.append("idCard:\""+idCard+"\",");
        buffer.append("travelDate:\""+travelDate+"\",");
        buffer.append("departDate:\""+departDate+"\",");
        buffer.append("bookBeginTime:\""+bookBeginTime+"\",");
        buffer.append("bookEndTime:\""+bookEndTime+"\",");
        buffer.append("visitPerson:[");
        int size = visitPerson.size();
        int i = 0;
        for (VisitPerson person : visitPerson) {
            buffer.append("{");
            buffer.append("name:\""+person.getName()+"\",");
            buffer.append("mobile:\""+person.getMobile()+"\",");
            buffer.append("idCard:\""+person.getIdCard()+"\"");
            if (i++<size-1){
                buffer.append("},");
            }else {
                buffer.append("}");
            }
        }
        buffer.append("],");
        buffer.append("address:"+"{");
        buffer.append("name:\""+address.getName()+"\",");
        buffer.append("mobile:\""+address.getMobile()+"\",");
        buffer.append("address:\""+address.getAddress()+"\"}");
        buffer.append("}");
        String data = buffer.toString();
        //.返回参数
        String result = new String();
        //.定义时间
        long st = System.currentTimeMillis() / 1000;
        //.定义方法
        String method = "CreateOrder";
        //加密将json格式的业务参数进行des加密，加密模式ECB充方式 PKCS7Padding,密钥为user_key。
        String encrypt = null;
        try {
            encrypt = encrypt(data, user_key);
        } catch (Exception e) {
            e.printStackTrace();
        }
        String md5 = getMD5(user_id + method + st + version + encrypt + user_key);
        //.封装JSON格式数据
        RequestHead requestHead = new RequestHead();
        requestHead.setUser_id(user_id);
        requestHead.setMethod(method);
        requestHead.setTimestamp(st);
        requestHead.setVersion(version);
        requestHead.setSign(md5);
        json.put("requestHead", requestHead);
        json.put("requestBody", encrypt);
        //.请求地址URL
        String url = "http://service.zhuxiaoke.cn/Tongcheng/ProcessRequest/";
        //.发送请求
        String resultInfo = restTemplate.postForObject(url, json, String.class);
        System.out.println(resultInfo);
        try {
            result = decrypt((String) JsonUtils.toMap(resultInfo).get("responseBody"), user_key);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(result);
        return result;
    }


    /**
     * @param
     * @description:查询接口
     * @return:
     * @author:作者:YF
     * @time:日期:2021/5/22 时间:15:09
     */
    public String QueryOrder(String orderSerialId,String partnerOrderId) {
        JSONObject json = new JSONObject();
        //.返回参数
        String result = new String();
        //.定义时间
        long st = System.currentTimeMillis() / 1000;
        //.定义方法
        String method = "QueryOrder";
        //加密将json格式的业务参数进行des加密，加密模式ECB充方式 PKCS7Padding,密钥为user_key。
        String encrypt = null;
        try {
            json.put("orderSerialId",orderSerialId);
            json.put("partnerOrderId",partnerOrderId);
            encrypt = encrypt("{"+"orderSerialId:"+"\""+json.get("orderSerialId")+"\","+
                    "partnerOrderId:"+"\""+json.get("partnerOrderId")+"\""+"}", user_key);
        } catch (Exception e) {
            e.printStackTrace();
        }
        String md5 = getMD5(user_id + method + st + version + encrypt + user_key);
        //.封装JSON格式数据
        RequestHead requestHead = new RequestHead();
        requestHead.setUser_id(user_id);
        requestHead.setMethod(method);
        requestHead.setTimestamp(st);
        requestHead.setVersion(version);
        requestHead.setSign(md5);
        json.put("requestHead", requestHead);
        json.put("requestBody", encrypt);
        //.请求地址URL
        String url = "http://service.zhuxiaoke.cn/Tongcheng/ProcessRequest/";
        //.发送请求
        String resultInfo = restTemplate.postForObject(url, json, String.class);
        System.out.println(resultInfo);
        try {
            result = decrypt((String) JsonUtils.toMap(resultInfo).get("responseBody"), user_key);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(result);
        return result;


    }


    /**
     * @description:退单接口（平台提供）
     * @param
     * @return:
     * @author:作者:YF
     * @time:日期:2021/5/22 时间:15:26
     */
    public String CancelOrder(String orderSerialId,String partnerOrderId,String reason,Integer tickets){
        JSONObject json = new JSONObject();
        //.返回参数
        String result = new String();
        //.定义时间
        long st = System.currentTimeMillis() / 1000;
        //.定义方法
        String method = "CancelOrder";
        //加密将json格式的业务参数进行des加密，加密模式ECB充方式 PKCS7Padding,密钥为user_key。
        String encrypt = null;
        try {
            json.put("orderSerialId",orderSerialId);
            json.put("partnerOrderId",partnerOrderId);
            json.put("reason",reason);
            json.put("tickets",tickets);
            encrypt = encrypt("{"+"orderSerialId:\""+json.get("orderSerialId")+"\","
                    +"partnerOrderId:\""+json.get("partnerOrderId")+"\","
                    +"reason:\""+json.get("reason")+"\","
                    +"tickets:"+json.get("tickets")
                    +"}", user_key);
        } catch (Exception e) {
            e.printStackTrace();
        }
        String md5 = getMD5(user_id + method + st + version + encrypt + user_key);
        //.封装JSON格式数据
        RequestHead requestHead = new RequestHead();
        requestHead.setUser_id(user_id);
        requestHead.setMethod(method);
        requestHead.setTimestamp(st);
        requestHead.setVersion(version);
        requestHead.setSign(md5);
        json.put("requestHead", requestHead);
        json.put("requestBody", encrypt);
        //.请求地址URL
        String url = "http://service.zhuxiaoke.cn/Tongcheng/ProcessRequest/";
        //.发送请求
        String resultInfo = restTemplate.postForObject(url, json, String.class);
        System.out.println(resultInfo);
        try {
            result = decrypt((String) JsonUtils.toMap(resultInfo).get("responseBody"), user_key);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(result);
        return result;

    }



    /**
     *
     * @description:订单核销接口（平台提供）
     * @param
     * @return:
     *
     * @author:作者:YF
     * @time:日期:2021/5/22  时间:16:39
     */
    public String CheckTicket(String barcodeNo,Integer checkCount){
        JSONObject json = new JSONObject();
        //.返回参数
        String result = new String();
        //.定义时间
        long st = System.currentTimeMillis() / 1000;
        //.定义方法
        String method = "CheckTicket";
        //加密将json格式的业务参数进行des加密，加密模式ECB充方式 PKCS7Padding,密钥为user_key。
        String encrypt = null;
        try {
            json.put("barcodeNo",barcodeNo);
            json.put("checkCount",checkCount);
            encrypt = encrypt("{"+"barcodeNo:\""+json.get("barcodeNo")+"\","
                    +"checkCount:"+json.get("checkCount")
                    +"}", user_key);
        } catch (Exception e) {
            e.printStackTrace();
        }
        String md5 = getMD5(user_id + method + st + version + encrypt + user_key);
        //.封装JSON格式数据
        RequestHead requestHead = new RequestHead();
        requestHead.setUser_id(user_id);
        requestHead.setMethod(method);
        requestHead.setTimestamp(st);
        requestHead.setVersion(version);
        requestHead.setSign(md5);
        json.put("requestHead", requestHead);
        json.put("requestBody", encrypt);
        //.请求地址URL
        String url = "http://service.zhuxiaoke.cn/Tongcheng/ProcessRequest/";
        //.发送请求
        String resultInfo = restTemplate.postForObject(url, json, String.class);
        System.out.println(resultInfo);
        try {
            result = decrypt((String) JsonUtils.toMap(resultInfo).get("responseBody"), user_key);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(result);
        return result;
    }

    /**
     *
     * @description:订单核销通知接口
     * @param
     * @return:
     *
     * @author:作者:YF
     * @time:日期:2021/6/24  时间:16:30
     */
    public Result ConsumeNotice(String requestHead, String requestBody){
        long millis = System.currentTimeMillis() /1000;
        //1，获取user_id
        String userId = (String) JsonUtils.toMap(requestHead).get("user_id");
        //2.获取method
        String method = (String) JsonUtils.toMap(requestHead).get("method");
        //3.获取timestamp
        Long timestamp = (Long) JsonUtils.toMap(requestHead).get("timestamp");
        //4.获取version
        String versions = (String) JsonUtils.toMap(requestHead).get("version");
        //5.获取sign
        String sign = (String) JsonUtils.toMap(requestHead).get("sign");
        //6.获取requestBody
        String decrypt = null;
        Result result = new Result();
        //1.首先可以拿到几个加密参数就是user_id，method，timestamp，version+requestBody里的des加密后的参数,去解析MD5的参数,判断是否正确
        String mysign = getMD5(userId + method + timestamp + versions + requestBody);
        //.如果参数不等于则返回错误信息
        if (!userId.equals(user_id)&&!method.equals("ConsumeNotice")&&!EmptyUtils.isEmpty(timestamp)&&!versions.equals(version)&&!sign.equals(mysign)) {
            ResponseHead responseHead = new ResponseHead();
            responseHead.setRes_code("5003");
            responseHead.setRes_msg("签名验证失败");
            responseHead.setTimestamp(millis);
            result.setResponseHead(responseHead);
            result.setResponseBody("请求数据报错,请联系管理员");
            return result;
        }
        //2.拿requestBody去解码成所需的参数
        try {
            decrypt = decrypt(requestBody,user_key);
        } catch (Exception e) {
            e.printStackTrace();
        }
        String orderSerialId = (String) JsonUtils.toMap(decrypt).get("orderSerialId");
        String partnerOrderId = (String) JsonUtils.toMap(decrypt).get("partnerOrderId");
        Long tickets = (Long) JsonUtils.toMap(decrypt).get("tickets");
        String consumeDate = (String) JsonUtils.toMap(decrypt).get("consumeDate");
        if (EmptyUtils.isEmpty(orderSerialId)&&EmptyUtils.isEmpty(partnerOrderId)&&EmptyUtils.isEmpty(tickets)&&EmptyUtils.isEmpty(consumeDate)){
            ResponseHead responseHead = new ResponseHead();
            responseHead.setRes_code("5004");
            responseHead.setRes_msg("数据出错或为空");
            responseHead.setTimestamp(millis);
            result.setResponseHead(responseHead);
            result.setResponseBody("请求数据报错,请联系管理员");
            return result;
        }else {
            ResponseHead responseHead = new ResponseHead();
            responseHead.setRes_code("1000");
            responseHead.setRes_msg("操作成功");
            responseHead.setTimestamp(millis);
            result.setResponseHead(responseHead);
            result.setResponseBody("核销成功");
            return result;
        }
    }


    /**
     *
     * @description:测试订单核销接口方法
     * @param
     * @return:
     *
     * @author:作者:YF
     * @time:日期:2021/6/25  时间:11:33
     */
    public void  ConsumeNoticeTest(){
        //.返回参数
        String result = new String();
        //.定义时间
        long st = System.currentTimeMillis() / 1000;
        //封装请求参数
        StringBuffer buffer = new StringBuffer("");
        buffer.append("{");
        buffer.append("orderSerialId:\""+"sz571717851651807350"+"\",");
        buffer.append("partnerOrderId:\""+"1000071955"+"\",");
        buffer.append("tickets:"+"1"+",");
        buffer.append("consumeDate:\""+"2018-07-04 12:09:40"+"\"");
        buffer.append("}");
        System.out.println(buffer);
        String string = buffer.toString();
        //加密将json格式的业务参数进行des加密，加密模式ECB充方式 PKCS7Padding,密钥为user_key。
        String encrypt = null;
        try {
            encrypt = encrypt(string, user_key);
        } catch (Exception e) {
            e.printStackTrace();
        }
        String md5 = getMD5(user_id + "ConsumeNotice" + st + version + encrypt + user_key);
        //.封装JSON格式数据
        JSONObject json = new JSONObject();
        RequestHead requestHead = new RequestHead();
        requestHead.setUser_id(user_id);
        requestHead.setMethod("ConsumeNotice");
        requestHead.setTimestamp(st);
        requestHead.setVersion(version);
        requestHead.setSign(md5);
        json.put("requestHead", requestHead);
        json.put("requestBody", encrypt);
        //.请求地址URL
        String url = "http://service.zhuxiaoke.cn/Tongcheng/ProcessRequest/";
        //.发送请求
        String resultInfo = restTemplate.postForObject(url, json, String.class);
        System.out.println(resultInfo);
        try {
            result = decrypt((String) JsonUtils.toMap(resultInfo).get("responseBody"), user_key);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(result);
    }


















    /**
     *
     * @description:所有接口调用
     * @param
     * @return:
     *
     * @author:作者:YF
     * @time:日期:2021/5/24  时间:10:18
     */
    public String sendPostAll(String method,String data){
        //.返回参数
        String result = new String();
        //.定义时间
        long st = System.currentTimeMillis() / 1000;
        //加密将json格式的业务参数进行des加密，加密模式ECB充方式 PKCS7Padding,密钥为user_key。
        String encrypt = null;
        try {
            encrypt = encrypt(data, user_key);
        } catch (Exception e) {
            e.printStackTrace();
        }
        String md5 = getMD5(user_id + method + st + version + encrypt + user_key);
        //.封装JSON格式数据
        JSONObject json = new JSONObject();
        RequestHead requestHead = new RequestHead();
        requestHead.setUser_id(user_id);
        requestHead.setMethod(method);
        requestHead.setTimestamp(st);
        requestHead.setVersion(version);
        requestHead.setSign(md5);
        json.put("requestHead", requestHead);
        json.put("requestBody", encrypt);
        //.请求地址URL
        String url = "http://service.zhuxiaoke.cn/Tongcheng/ProcessRequest/";
        //.发送请求
        String resultInfo = restTemplate.postForObject(url, json, String.class);
        System.out.println(resultInfo);
        try {
            result = decrypt((String) JsonUtils.toMap(resultInfo).get("responseBody"), user_key);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(result);
        return result;
    }


    /**
     * 功能描述: 助销客退单通知接口
     * @Param: [request]
     * @return: com.shop.cereshop.app.dl.logic.domian.Result
     * @Author: 况鑫威
     * @Date: 2021/8/2
     * @Time: 14:57
     */
    @Transactional(isolation= Isolation.DEFAULT,propagation= Propagation.REQUIRED,rollbackFor = {CoBusinessException.class, Exception.class})
    public Result ZXKChargeback(String request) throws Exception {
        String requestBody = (String) JsonUtils.toMap(request).get("requestBody");
        JSONObject requestHead = (JSONObject) JsonUtils.toMap(request).get("requestHead");
        long millis = System.currentTimeMillis() / 1000;
        //1，获取user_id
        String userId = (String) requestHead.get("user_id");
        //2.获取method
        String method = (String) requestHead.get("method");
        //3.获取timestamp
        Integer timestamp = (Integer) requestHead.get("timestamp");
        //4.获取version
        String versions = (String) requestHead.get("version");
        //5.获取sign
        String sign = (String) requestHead.get("sign");
        //6.获取requestBody
        String decrypt = null;
        Result result = new Result();
        //1.首先可以拿到几个加密参数就是user_id，method，timestamp，version+requestBody里的des加密后的参数,去解析MD5的参数,判断是否正确
        String mysign = getMD5(userId + method + timestamp + versions + requestBody + user_key);
        //.如果参数不等于则返回错误信息
        if (userId.equals(user_id) && "RefundNotice".equals(method) && timestamp != null && versions.equals(version) && sign.equals(mysign)) {
            //2.拿requestBody去解码成所需的参数
            try {
                decrypt = decrypt(requestBody, user_key);
                System.out.println(decrypt);
            } catch (Exception e) {
                e.printStackTrace();
            }
            //退单流水号
            String orderSerialId = (String) JsonUtils.toMap(decrypt).get("orderSerialId");
            System.out.println(orderSerialId);
            //助销客订单号
            String partnerOrderld = (String) JsonUtils.toMap(decrypt).get("partnerOrderId");
            System.out.println(partnerOrderld);
            //退单审核状态 0失败  1成功
            String refundstatus = (String) JsonUtils.toMap(decrypt).get("refundStatus");
            System.out.println(refundstatus);
            //退款票数
            Integer tickets = (Integer) JsonUtils.toMap(decrypt).get("tickets");
            System.out.println(tickets);
            //分销商订单号
            String sellerOrderNo = (String) JsonUtils.toMap(decrypt).get("sellerOrderNo");
            System.out.println(tickets);
            //审核失败的原因
            String remark = (String) JsonUtils.toMap(decrypt).get("remark");
            System.out.println(remark);
            //操作时间
            String datetime = (String) JsonUtils.toMap(decrypt).get("datetime");
            System.out.println(datetime);


            StringBuilder buffer = new StringBuilder();
            ResponseHead responseHead = new ResponseHead();
            responseHead.setRes_code("1000");
            responseHead.setRes_msg("操作成功");
            responseHead.setTimestamp(millis);
            result.setResponseHead(responseHead);
            buffer.append("{")
                    .append("responseHead:{")
                    .append("res_code:")
                    .append(responseHead.getRes_code()).append(",")
                    .append("res_msg:").append(responseHead.getRes_msg()).append(",")
                    .append("timestamp:").append(responseHead.getTimestamp()).append("}")
                    .append("}");
            String toString = buffer.toString();
            try {
                String message = encrypt(toString, user_key);
                result.setResponseBody(message);
            } catch (Exception e) {
                e.printStackTrace();
            }

            //去数据库查询是否有该票务
            Integer orderForMid = cereShopOrderDAO.getByForMid(orderSerialId);
            //...用orderSerialId去查询orderId
            CereShopOrder cereShopOrder = cereShopOrderDAO.getShopOrderByForMid(orderSerialId);
            if(orderForMid != null && cereShopOrder != null){
                //用orderid查询售后订单
                CereOrderAfter cereOrderAfter = cereOrderAfterDAO.selectByOrderId(cereShopOrder.getOrderId());
                //审核失败
                if(refundstatus.equals("0")){
                    cereOrderAfter.setAfterState(5);
                    cereOrderAfter.setRemark(remark);
                    cereOrderAfterDAO.updateByPrimaryKeySelective(cereOrderAfter);
                    return result;
                    //审核成功
                }else{
                    cereOrderAfter.setAfterState(4);
                }
                cereOrderAfter.setRemark(remark);
                cereOrderAfterDAO.updateByPrimaryKeySelective(cereOrderAfter);


                //执行退款操作
                //根据售后单id查询订单支付信息和订单总金额
                Refund refund = cereOrderAfterDAO.findOrderPay(cereOrderAfter.getAfterId());
                //调用退款接口
                if (refund != null) {
                    //更新支付流水after字段
                    CerePayLog cerePayLog = new CerePayLog();
                    cerePayLog.setId(refund.getId());
                    if (!EmptyUtils.isEmpty(refund.getAfter())) {
                        //不是第一次退款,重新设置退款单号
                        if (refund.getOutTradeNo().contains("XCX")) {
                            //小程序支付
                            refund.setOutRefundNo("XCXTK" + TimeUtils.todayTime2() + refund.getOrderFormid());
                        } else if (refund.getOutTradeNo().contains("APP")) {
                            //APP支付
                            refund.setOutRefundNo("APPTK" + TimeUtils.todayTime2() + refund.getOrderFormid());
                        }
                        cerePayLog.setAfter(refund.getAfter() + "," + cereOrderAfter.getAfterId());
                    } else {
                        cerePayLog.setAfter(String.valueOf(cereOrderAfter.getAfterId()));
                    }
                    cerePayLogService.update(cerePayLog);
                    Map<String, String> resultMap = wxPayService.refund(refund.getTransactionId(), refund.getOutRefundNo(), refund.getOrderPrice(), refund.getPrice());
                    if (!EmptyUtils.isEmpty(resultMap)) {
                        if (resultMap.get("return_msg").equals(WxPayEnum.REFUND_SUCCESS.getCode()) &&
                                resultMap.get("return_code").equals(WxPayEnum.REFUND_OK.getCode())) {
                            //退款成功
                        } else if (resultMap.get("return_code").equals(WxPayEnum.BUSINESS_BALANCE_NOTENOUGH.getCode())) {
                            //退款失败,商户余额不足
                            throw new CoBusinessException(CoReturnFormat.BUSINESS_BALANCE_NOT);
                        }
                    }
                }
                //删除自动确认收货延时任务
                stringRedisService.delete(StringEnum.ORDER_CONFIRM_DILEVERY.getCode() + "-" + cereOrderAfter.getOrderId());
                cereRedisKeyServcice.deleteByKey(StringEnum.ORDER_CONFIRM_DILEVERY.getCode() + "-" + cereOrderAfter.getOrderId());
                //清空自动关闭售后延时任务和任务记录
                stringRedisService.delete(StringEnum.AFTER_CANCEL.getCode() + "-" + cereOrderAfter.getAfterId());
                cereRedisKeyServcice.deleteByKey(StringEnum.AFTER_CANCEL.getCode() + "-" + cereOrderAfter.getAfterId());
                //新增日志
                cerePlatformLogService.addLog(buyerUserId, "售后管理", "商户端操作", "仅退款同意退款申请", cereOrderAfter.getAfterId(), TimeUtils.yyMMddHHmmss());
            }
            return result;
        }else{
            StringBuilder builder = new StringBuilder();
            ResponseHead responseHead = new ResponseHead();
            responseHead.setRes_code("5003");
            responseHead.setRes_msg("签名验证失败");
            responseHead.setTimestamp(millis);
            result.setResponseHead(responseHead);
            builder.append("{");
            builder.append("responseHead:{");
            builder.append("res_code:").append(responseHead.getRes_code()).append(",");
            builder.append("res_msg:").append(responseHead.getRes_msg()).append(",");
            builder.append("timestamp:").append(responseHead.getTimestamp()).append("}");
            builder.append("}");
            String toString = builder.toString();
            try {
                String message = encrypt(toString, user_key);
                result.setResponseBody(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }
    }


//=======================================================================================================================================================================

    /**
     * Description 根据键值进行加密
     *
     * @param data
     * @param key  加密键byte数组
     * @return
     * @throws Exception
     */
    public static String encrypt(String data, String key) throws Exception {
        byte[] bt = encrypt(data.getBytes("UTF-8"), key.getBytes("UTF-8"));
        String strs = new BASE64Encoder().encode(bt);
        return strs;
    }

    /**
     * Description 根据键值进行解密
     *
     * @param data
     * @param key  加密键byte数组
     * @return
     * @throws IOException
     * @throws Exception
     */
    public static String decrypt(String data, String key) throws Exception {
        if (data == null) {
            return null;
        }
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] buf = decoder.decodeBuffer(data);
        byte[] bt = decrypt(buf, key.getBytes("UTF-8"));
        return new String(bt, "UTF-8");
    }


    /**
     * Description 根据键值进行加密
     *
     * @param data
     * @param key  加密键byte数组
     * @return
     * @throws Exception
     */
    private static byte[] encrypt(byte[] data, byte[] key) throws Exception {
        // 生成一个可信任的随机数源
        SecureRandom sr = new SecureRandom();

        // 从原始密钥数据创建DESKeySpec对象
        DESKeySpec dks = new DESKeySpec(key);

        // 创建一个密钥工厂，然后用它把DESKeySpec转换成SecretKey对象
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey securekey = keyFactory.generateSecret(dks);

        // Cipher对象实际完成加密操作
        Cipher cipher = Cipher.getInstance("DES");

        // 用密钥初始化Cipher对象
        cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);

        return cipher.doFinal(data);
    }

    public static String getMD5(String content) {
        String result = "";
        try {
            MessageDigest md = MessageDigest.getInstance("md5");
            md.update(content.getBytes());
            byte[] bytes = md.digest();
            StringBuilder sb = new StringBuilder();
            for (byte b : bytes) {
                String str = Integer.toHexString(b & 0xFF);
                if (str.length() == 1) {
                    sb.append("0");
                }
                sb.append(str);
            }
            result = sb.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * Description 根据键值进行解密
     *
     * @param data
     * @param key  加密键byte数组
     * @return
     * @throws Exception
     */
    private static byte[] decrypt(byte[] data, byte[] key) throws Exception {
        // 生成一个可信任的随机数源
        SecureRandom sr = new SecureRandom();

        // 从原始密钥数据创建DESKeySpec对象
        DESKeySpec dks = new DESKeySpec(key);

        // 创建一个密钥工厂，然后用它把DESKeySpec转换成SecretKey对象
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey securekey = keyFactory.generateSecret(dks);

        // Cipher对象实际完成解密操作
        Cipher cipher = Cipher.getInstance("DES");

        // 用密钥初始化Cipher对象
        cipher.init(Cipher.DECRYPT_MODE, securekey, sr);

        return cipher.doFinal(data);
    }




}
